package middleware

import (
	"fmt"
	"manage/internal/routes/common"
	"net/http"
	"runtime/debug"
	"time"

	"github.com/Fromsko/gouitls/logs"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

var (
	Log      = logs.InitLogger()
	upgrader = websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			// 在这里定义允许的源，例如允许所有源：
			return true
		},
	}
)

func ErrorHttp(c *gin.Context) {
	defer func() {
		if r := recover(); r != nil {
			//打印错误堆栈信息
			Log.Errorf("panic: %v\n", r)
			debug.PrintStack()
			c.JSON(500, "服务器异常")
		}
	}()
	c.Next()
}

func OriginPort(c *gin.Context) {
	sourcePort := c.Request.Host
	if sourcePort != "8080" {
		c.JSON(403, gin.H{"msg": "无权访问", "err": "非客户端访问!"})
		c.Abort()
		return
	}
	c.Next()
}

func MonitorWS(c *gin.Context) {
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Println("WebSocket upgrade error:", err)
		return
	}

	defer func(conn *websocket.Conn) {
		_ = conn.Close()
	}(conn)

	// 定义心跳间隔
	heartbeatInterval := 3 * time.Second

	// 创建一个定时器
	heartbeatTimer := time.NewTicker(heartbeatInterval)

	for {
		select {
		case <-heartbeatTimer.C:
			if err := conn.WriteJSON(common.Msg{Type: "ping"}); err != nil {
				fmt.Println("WebSocket write error:", err)
				return
			}

		default:
			// 检查消息队列是否为空
			if !common.MsgQueue.IsEmpty() {
				message := common.MsgQueue.Dequeue()
				if message != nil {
					err := conn.WriteJSON(message)
					if err != nil {
						fmt.Println("WebSocket write error:", err)
						return
					}
				}
			}
		}
		// 短暂休眠，避免过度占用 CPU
		time.Sleep(time.Millisecond * 100)
	}
}

func LoggerWithFormatter(params gin.LogFormatterParams) string {
	var statusColor, methodColor, resetColor string
	statusColor = params.StatusCodeColor()
	methodColor = params.MethodColor()
	resetColor = params.ResetColor()
	return fmt.Sprintf(
		"[Online-Server] %s  | %s %d  %s | \t %s | %s | %s %-7s %s \t  %s\n",
		params.TimeStamp.Format("2006/01/02 - 15:04:05"),
		statusColor, params.StatusCode, resetColor,
		params.ClientIP,
		params.Latency,
		methodColor, params.Method, resetColor,
		params.Path,
	)
}
